package de.mnit.basis.daten;


import java.util.Random;

import de.mnit.basis.daten.konstant.ZEICHEN;
import de.mnit.basis.daten.struktur.S_Folge;
import de.mnit.basis.daten.struktur.liste.Liste;
import de.mnit.basis.daten.struktur.liste.S_Liste;
import de.mnit.basis.daten.typ.zeit.S_Datum;
import de.mnit.basis.fehler.Fehler;

/**
 * @author Michael Nitsche
 * 18.03.2007	Erstellt
 */
public class Zufall {

	private static final Random r=new Random();


	public static int zahl(int min, int max) {
		return min+r.nextInt(max-min+1);
	}

	public static String text(int laenge, boolean grossklein, boolean zahlen) {
		return zeichenfolge(laenge, true, grossklein, zahlen, null);
	}

	public static String zahlen(int laenge) {
		return zeichenfolge(laenge, false, false, true, null);
	}

	public static String zeichenfolge(int laenge, boolean klein, boolean gross, boolean zahlen, String sonstige) {
		String auswahl="";
		if(klein)
			auswahl+=ZEICHEN.ABC.toLowerCase();
		if(gross)
			auswahl+=ZEICHEN.ABC.toUpperCase();
		if(zahlen)
			auswahl+=ZEICHEN.DEZIMAL;
		if(sonstige!=null)
			auswahl+=sonstige;
		StringBuffer sb=new StringBuffer();
		for(int i=0; i<laenge; i++)
			sb.append(auswahl.charAt(zahl(0,auswahl.length()-1)));
		return sb.toString();
	}

	public static boolean bool() {
		return r.nextBoolean();
	}

	public static byte[] bytes(int anzahl) {
		Fehler.zahl.wenn_ZuKlein(0, anzahl);
		byte[] erg=new byte[anzahl];
		r.nextBytes(erg);
		return erg;
	}

	public static int[] intArray(int anzahl, int min, int max) {
		Fehler.zahl.wenn_ZuKlein(0, anzahl);
		int[] erg=new int[anzahl];
		for(int p=0; p<anzahl; p++)
			erg[p]=Zufall.zahl(min, max);
		return erg;
	}

	public static <T> S_Folge<T> auswahl(S_Folge<T> pool, int anzahl, boolean doppelte) {
		if(!doppelte)
			Fehler.zahl.wenn_ZuGross(pool.gLaenge(), anzahl);
		S_Liste<T> erg=Liste.neu();
		if(doppelte) {
			S_Liste<Integer> temp=Liste.neu();
			for(int nr=1; nr<=anzahl; nr++)
				temp.plus(Zufall.zahl(1, pool.gLaenge()));
			for(Integer i : temp)
				erg.plus(pool.gib(i));
		}
		else {
			boolean[] temp=new boolean[pool.gLaenge()];
			int ist=0;
			while(ist<anzahl) {
				int z=Zufall.zahl(0, pool.gLaenge()-1);
				if(!temp[z]) {
					temp[z]=true;
					ist++;
				}
			}
			for(int i=1; i<=pool.gLaenge(); i++)
				if(temp[i-1])
					erg.plus(pool.gib(i));
		}
		return erg;
	}

	public static S_Datum datum(S_Datum von, S_Datum bis) { //TODO Testen und ggf. optimieren!
		Fehler.objekt.wenn_Null(von, bis);
		int diff=(int)von.diffTage(bis);
		Fehler.zahl.wenn_ZuKlein(1, diff);
		return von.gPlusTage(zahl(0, diff));
	}

	public static S_Liste<String> textListe(int anzahl, int laenge_min, int laenge_max, boolean grossklein, boolean zahlen) {
		S_Liste<String> liste=Liste.neu();
		for(int i=1; i<=anzahl; i++) {
			int laenge=Zufall.zahl(laenge_min, laenge_max);
			String text=Zufall.text(laenge, grossklein, zahlen);
			liste.plus(text);
		}
		return liste;
	}

}
